home *** CD-ROM | disk | FTP | other *** search
- /*
- File: RotateString.c
-
- Contains: This function will return a BitMap that contains the
- text passed rotated 90°
-
- The font characteristics are copied from
- the current port before creating the BitMap.
-
-
- Written by: RT and BS
-
- Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 08/2000 JM Carbonized, non-Carbon code is commented out
- for demonstration purposes.
- 7/14/1999 KG Updated for Metrowerks Codewarror Pro 2.1
-
- 8/27/92 BS added a direction parameter to the end. It will
- rotate in the direction you specify. ALSO fixed
- some LAME bugs, such as the rotate routine did not
- preserve the current port,and it also did not dispose
- of a temporary bitmap it used. Should be in good
- shape now.
-
- */
- #include "CarbonPrefix.h"
- #include <Memory.h>
- #include <QDOffscreen.h>
- #include "RotateString.h"
-
- /*
- In pascal this is:
-
- function RotateString (str: Str255; var destMap: BitMap, direction : integer): OSErr;
-
- */
-
-
- pascal OSErr RotateString( Str255 str, BitMap *destMap, short direction)
- {
- //GrafPort srcPort;
- //GrafPtr srcPortPtr;
- char *srcPtr, *destPtr;
- FontInfo f;
- short heightBits, heightBytes;
- short width, widthBytes;
- short rotateWidth;
- short rotateHeight;
- short row, column;
- short texFont,texFace,texMode,texSize;
- short err;
- //Rect tempRect1;
- RgnHandle rgnHandle = NewRgn();
- CGrafPtr currentPort; /* Saved CGrafPtr for later restore. */
- GDHandle currentDevice; /* Saved device for later restore. */
- GWorldPtr sourceGWorld;
- Rect rect;
- int sourceRowBytes;
-
-
- GetGWorld( ¤tPort, ¤tDevice );
-
- /*texFont = qd.thePort->txFont;
- texFace = qd.thePort->txFace;
- texMode = qd.thePort->txMode;
- texSize = qd.thePort->txSize;*/
-
- texFont = GetPortTextFont(GetQDGlobalsThePort());
- texFace = GetPortTextFace(GetQDGlobalsThePort());
- texMode = GetPortTextMode(GetQDGlobalsThePort());
- texSize = GetPortTextSize(GetQDGlobalsThePort());
-
- //OpenPort( &srcPort);
- //srcPortPtr = CreateNewPort();
- //SetPort(&srcPort);
- //SetPort(srcPortPtr);
-
- TextFont(texFont);
- TextFace(texFace);
- TextMode(texMode);
- TextSize(texSize);
- GetFontInfo( &f);
-
- heightBits = f.ascent + f.descent + f.leading;
- heightBytes = ((heightBits + 7) & 0x7FF8) >> 3;
- width = StringWidth( str );
- widthBytes = ((width + 7) & 0x7FF8) >> 3;
-
- rotateWidth = heightBytes;
- rotateHeight = widthBytes << 3;
-
- //srcPort.portBits.baseAddr = NewPtrClear( widthBytes * heightBits);
- /*(*(GetPortPixMap(srcPortPtr)))->baseAddr = NewPtrClear( widthBytes * heightBits );
- if(err = MemError()) return err;
-
- //srcPort.portBits.rowBytes = widthBytes;
- (*(GetPortPixMap(srcPortPtr)))->rowBytes = widthBytes;
- //SetRect( &srcPort.portBits.bounds, 0, 0, width, heightBits);
- SetRect( GetPortBounds(srcPortPtr, &tempRect1), 0, 0, width, heightBits );*/
- SetRect( &rect, 0, 0, width, heightBits );
- NewGWorld( &sourceGWorld, 1, &rect, nil, nil, 0 );
- SetGWorld( sourceGWorld, nil );
- EraseRect(&rect);
-
- TextFont(texFont);
- TextFace(texFace);
- TextMode(texMode);
- TextSize(texSize);
-
- sourceRowBytes = GetPixRowBytes(GetGWorldPixMap(sourceGWorld));
-
- destMap->baseAddr = NewPtrClear( rotateWidth * rotateHeight);
- if(err = MemError()) {
- //DisposePtr(srcPort.portBits.baseAddr);
- DisposeGWorld(sourceGWorld);
- return err;
- }
-
- destMap->rowBytes = rotateWidth;
- SetRect( &destMap->bounds, 0, 0, rotateWidth * 8, rotateHeight);
-
- //RectRgn(srcPort.visRgn,&srcPort.portBits.bounds);
- RectRgn(GetPortVisibleRegion(sourceGWorld, rgnHandle), &(*(GetGWorldPixMap(sourceGWorld)))->bounds);
- MoveTo( 0, f.ascent); // change 2.0.1 <CKH> was heightBits
- DrawString( str );
-
-
- /*****************************************/
- /* Rotate Algorithm */
- /*****************************************/
-
- LockPixels(GetGWorldPixMap(sourceGWorld));
- //srcPtr = srcPort.portBits.baseAddr; // Start at the Top,Left
- srcPtr = (*(GetGWorldPixMap(sourceGWorld)))->baseAddr;
-
- if(direction == counterClockWise) // Start at the Bottom,Left
- destPtr = destMap->baseAddr + ((rotateHeight-1) * rotateWidth);
- else // Start at the Top,Left
- destPtr = destMap->baseAddr;
-
- for( column = 0; column < width; column++) /* width is in pixels */
- {
- for( row = 0; row < heightBits; row++) /* height in pixels, too */
- {
-
- if(direction == counterClockWise) {
- /* We are rotating left ( counter clock-wise) thus */
- /* as we search across the top of the horizontal pixel bit map, */
- /* we write down the right edge of the vertical pixel bit map */
-
- if( *(srcPtr /* Begin with the upper left corner */
- //+ (row*widthBytes) /* Move down a row */
- + (row * sourceRowBytes)
- + (column >> 3)) /* Go to the first even byte */
- & (0x80>>(column & 7)) ) /* calculate a shifted bit position based on the column */
- {
- *(destPtr /* Begin in the lower left corner */
- - (column*rotateWidth) /* Subtract, move up for each row */
- + (row >> 3)) /* Calculate a bit position for the column */
- |= (0x80>>(row & 7)); /* Set a bit based on the column */
- }
- } else { /* clockWise */
- /* We are rotating right (clock-wise) thus */
- /* as we search across the top of the horizontal pixel bit map, */
- /* we write down the left edge of the vertical pixel bit map */
-
- if( *(srcPtr /* Begin with the upper left corner */
- //+ (row*widthBytes) /* Move down a row */
- + (row * sourceRowBytes)
- + (column >> 3)) /* Go to the first even byte */
- & (0x80>>(column & 7)) ) /* calculate a shifted bit position based on the column */
- {
- *(destPtr /* Begin in the lower left corner */
- + (column*rotateWidth) /* Add, move down for each row */
- - (row >> 3)) /* Calculate a bit position for the column */
- |= (0x01<<(row & 7)); /* Set a bit based on the column */
- }
- }
- }
- }
-
- /* clean up the used source BitMap, and restore the ports properly */
- //DisposePtr(srcPort.portBits.baseAddr);
- UnlockPixels(GetGWorldPixMap(sourceGWorld));
- DisposeGWorld(sourceGWorld);
- //ClosePort(&srcPort);
- SetGWorld( currentPort, currentDevice );
- DisposeRgn(rgnHandle);
-
- return noErr;
- }
-